package com.example.pay.service.channel;

import com.example.pay.config.PayProperties;
import com.example.pay.dto.PrepayResponse;
import com.example.pay.entity.MemberOrder;
import com.example.pay.entity.MemberPackageItem;
import com.example.pay.util.RsaSignUtil;
import com.example.pay.util.PemUtil;
import com.example.pay.util.WeChatV3AuthUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
@RequiredArgsConstructor
public class WeChatPayService implements ChannelPayService {
    private final PayProperties properties;
    private final RestTemplate restTemplate = new RestTemplate();
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public PrepayResponse prepay(MemberOrder order, MemberPackageItem item) {
        String appId = properties.getWechat().getAppId();
        String mchId = properties.getWechat().getMchId();
        String notifyUrl = properties.getWechat().getNotifyUrl();

        int totalCents = order.getPayAmount().movePointRight(2).setScale(0, java.math.RoundingMode.HALF_UP).intValueExact();
        String bodyJson = String.format("{\"appid\":\"%s\",\"mchid\":\"%s\",\"description\":\"%s\",\"out_trade_no\":\"%s\",\"notify_url\":\"%s\",\"amount\":{\"total\":%d,\"currency\":\"CNY\"}}",
                appId, mchId, item.getItemDesc(), order.getOrderCode(), notifyUrl, totalCents);

        String canonicalUrl = "/v3/pay/transactions/app";
        String merchantPrivateKeyPem = PemUtil.loadPem(properties.getWechat().getMerchantPrivateKey());
        WeChatV3AuthUtil.AuthHeader auth = WeChatV3AuthUtil.buildAuth(
                "POST", canonicalUrl, bodyJson, mchId,
                properties.getWechat().getMerchantCertificateSerial(),
                merchantPrivateKeyPem);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("Authorization", auth.header);
        headers.add("Accept", "application/json");

        HttpEntity<String> entity = new HttpEntity<>(bodyJson, headers);
        String response = restTemplate.postForObject("https://api.mch.weixin.qq.com" + canonicalUrl, entity, String.class);

        String prepayId;
        try {
            JsonNode root = objectMapper.readTree(response);
            prepayId = root.path("prepay_id").asText();
            if (prepayId == null || prepayId.isEmpty()) {
                throw new IllegalStateException("微信统一下单返回异常: " + response);
            }
        } catch (Exception e) {
            throw new RuntimeException("微信统一下单失败", e);
        }

        String nonceStr = UUID.randomUUID().toString().replace("-", "");
        String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
        // v3 App 调起支付签名串，顺序为 appId, timeStamp, nonceStr, prepayId，末尾需换行
        String toSign = appId + "\n" + timeStamp + "\n" + nonceStr + "\n" + prepayId + "\n";
        String paySign = RsaSignUtil.signSHA256withRSA(toSign, merchantPrivateKeyPem);

        Map<String, String> payload = new HashMap<>();
        payload.put("appId", appId);
        payload.put("partnerId", mchId);
        payload.put("prepayId", prepayId);
        payload.put("package", "Sign=WXPay");
        payload.put("nonceStr", nonceStr);
        payload.put("timeStamp", timeStamp);
        payload.put("signType", "RSA");
        payload.put("paySign", paySign);

        return new PrepayResponse("WECHAT", order.getOrderCode(), payload,true);
    }
}
